package com.mmall.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.mmall.common.Const;
import com.mmall.common.ResponseCode;
import com.mmall.common.ServerResponse;
import com.mmall.dao.*;
import com.mmall.pojo.*;
import com.mmall.service.IOrderService;
import com.mmall.utils.BigDecimalUtil;
import com.mmall.utils.DateTimeUtil;
import com.mmall.utils.PropertiesUtil;
import com.mmall.vo.OrderItemVo;
import com.mmall.vo.OrderProductVo;
import com.mmall.vo.OrderVo;
import com.mmall.vo.ShippingVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.schema.Server;
import org.apache.commons.collections.CollectionUtils;
import org.aspectj.weaver.ast.Or;
import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Random;


@Service("iOrderService")
@Slf4j
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ShippingMapper shippingMapper;


    //===========backend==================//


    public ServerResponse manageSearch(Long orderNo, Integer pageNum, Integer pageSize) {
        if (orderNo == null) {
            return ServerResponse.createByError();
        }
        PageHelper.startPage(pageNum, pageSize);

        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            return ServerResponse.createByErrorMessage("订单不存在");
        }
        List<OrderItem> orderItemList = orderItemMapper.selectByUserIdAndOrderNo(null, orderNo);
        OrderVo orderVo = assembleOrderVo(order, orderItemList);

        PageInfo pageInfo = new PageInfo(Lists.newArrayList(orderVo));
        pageInfo.setList(Lists.newArrayList(orderVo));
        return ServerResponse.createBySuccess(pageInfo);
    }


    public ServerResponse sendGoods(Long orderNo) {
        Order order = orderMapper.selectByOrderNo(orderNo);
        if (order == null) {
            return ServerResponse.createByErrorMessage("订单不存在");
        }
        if (order.getStatus() == Const.OrderStatusEnum.PAYED.getCode()) {
            order.setStatus(Const.OrderStatusEnum.SHIPPED.getCode());
            order.setSendTime(new Date());
            int rowCount = orderMapper.updateByPrimaryKeySelective(order);
            if (rowCount > 0) {
                return ServerResponse.createBySuccessMessage("订单发货成功");
            }
        }
        return ServerResponse.createBySuccessMessage("订单发货失败");
    }

    //==========protal========================//


    public ServerResponse cancelOrder(Integer userId, Long orderNo) {
        if (userId == null || orderNo == null) {
            return ServerResponse.createByError(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getMsg());
        }
        Order order = orderMapper.selectByUserIdOrderNo(userId, orderNo);
        if (order == null) {
            return ServerResponse.createByErrorMessage("没有找到该订单");
        }
        if (order.getStatus() != Const.OrderStatusEnum.NO_PAYED.getCode()) {
            return ServerResponse.createByErrorMessage("订单已支付,无法取消");
        }
        order.setStatus(Const.OrderStatusEnum.CANCELED.getCode());

        int rowCount = orderMapper.updateByPrimaryKeySelective(order);
        if (rowCount > 0) {
            return ServerResponse.createBySuccess();
        }
        return ServerResponse.createByErrorMessage("系统异常,订单无法取消,请稍后再试");
    }


    public ServerResponse getOrderDetail(Integer userId, Long orderNo) {
        if (orderNo == null) {
            return ServerResponse.createByError(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getMsg());
        }
        Order order = orderMapper.selectByUserIdOrderNo(userId, orderNo);
        if (order == null) {
            return ServerResponse.createByErrorMessage("未找到该订单");
        }
        List<OrderItem> orderItemList = orderItemMapper.selectByUserIdAndOrderNo(userId, orderNo);
        OrderVo orderVo = assembleOrderVo(order, orderItemList);
        return ServerResponse.createBySuccess(orderVo);
    }


    public ServerResponse getOrderList(Integer userId, Integer pageNum, Integer pageSize) {
        if (userId == null || pageNum == null || pageSize == null) {
            return ServerResponse.createBySuccess();
        }
        PageHelper.startPage(pageNum, pageSize);

        List<Order> orderList = orderMapper.selectByUserId(userId);
        List<OrderVo> orderVoList = assembleOrderVoList(userId, orderList);
//        PageInfo pageInfo = new PageInfo(orderList);
        //TODO 为什么不使用上面的方法
        PageInfo pageInfo = new PageInfo(orderList);
        pageInfo.setList(orderVoList);
        return ServerResponse.createBySuccess(pageInfo);
    }

    private List<OrderVo> assembleOrderVoList(Integer userId, List<Order> orderList) {
        List<OrderVo> orderVoList = Lists.newArrayList();
        if (userId == null || CollectionUtils.isEmpty(orderList)) {
            return orderVoList;
        }
        List<OrderItem> orderItemList = null;
        for (Order order : orderList) {
            orderItemList = orderItemMapper.selectByUserIdAndOrderNo(userId, order.getOrderNo());
            OrderVo orderVo = assembleOrderVo(order, orderItemList);
            orderVoList.add(orderVo);
        }
        return orderVoList;
    }


    //order-->orderItemVo-->list-->orderProductVo
    public ServerResponse orderCartProduct(Integer userId) {
        if (userId == null) {
            log.error("获取购物车数据错误");
            return ServerResponse.createByError();
        }
        List<Cart> cartList = cartMapper.selectCheckedByUserId(userId);
        ServerResponse serverResponse = this.generateOrderItem(userId, cartList);
        if (!serverResponse.is_success()) {
            return ServerResponse.createByErrorMessage("购物车数据为空");
        }
        List<OrderItem> orderItemList = (List<OrderItem>) serverResponse.getData();
        List<OrderItemVo> orderItemVoList = Lists.newArrayList();

        BigDecimal payment = new BigDecimal("0");

        for (OrderItem orderItem : orderItemList) {
            OrderItemVo orderItemVo = this.assembleOrderItemVo(orderItem);
            payment = BigDecimalUtil.add(payment.doubleValue(), orderItemVo.getTotalPrice().doubleValue());
            orderItemList.add(orderItem);
        }
        OrderProductVo orderProductVo = new OrderProductVo();
        orderProductVo.setImgHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));
        orderProductVo.setOrderItemVoList(orderItemVoList);
        orderProductVo.setProductTotalPrice(payment);

        return ServerResponse.createBySuccess(orderProductVo);
    }


    public ServerResponse createOrder(Integer userId, Integer shippingId) {
        if (userId == null || shippingId == null) {
            return ServerResponse.createByError(ResponseCode.ILLEGAL_ARGUMENT.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getMsg());
        }
        //查询用户的购物车，并创建相关对象
        List<Cart> carts = cartMapper.selectCheckedByUserId(userId);
        //计算购物车总价，需要校验商品数据并封装数据
        ServerResponse serverResponse = generateOrderItem(userId, carts);
        if (!serverResponse.is_success()) {
            return serverResponse;
        }
        List<OrderItem> orderItemList = (List<OrderItem>) serverResponse.getData();
        BigDecimal payment = getOrderTotalPrice(orderItemList);

        //生成订单
        Order order = assembleOrder(userId, shippingId, payment);
        if (order == null) {
            return ServerResponse.createByErrorMessage("生成订单失败");
        }
        if (CollectionUtils.isEmpty(orderItemList)) {
            return ServerResponse.createByErrorMessage("购物车为空");
        }
        //orderItem设置编号
        for (OrderItem orderItem : orderItemList) {
            orderItem.setOrderNo(order.getOrderNo());
        }
        //批量插入数据
        int rowCount = orderItemMapper.batchInsert(orderItemList);
        if (rowCount <= 0) {
            log.error("购物车子项数据插入失败");
            return ServerResponse.createByErrorMessage("数据插入失败:" + rowCount);
        }
        //减少商品库存
        this.reduceProductStock(orderItemList);

        //清除购物车
        this.clearCart(orderItemList);

        //返回订单对象OrderVo
        OrderVo orderVo = assembleOrderVo(order, orderItemList);
        return ServerResponse.createBySuccess(orderVo);
    }

    private OrderVo assembleOrderVo(Order order, List<OrderItem> orderItemList) {
        OrderVo orderVo = new OrderVo();
        orderVo.setOrderNo(order.getOrderNo());
        orderVo.setPayment(order.getPayment());
        orderVo.setShippingId(order.getShippingId());
        orderVo.setPaymentType(order.getPaymentType());
        orderVo.setPaymentTypeDesc(Const.PaymentTypeEnum.valueOf(order.getPaymentType()).getDesc());

        orderVo.setImageHost(PropertiesUtil.getProperty("ftp.server.http.prefix"));
        orderVo.setStatus(order.getStatus());
        orderVo.setStatusDesc(Const.PaymentTypeEnum.valueOf(order.getStatus()).getDesc());
        orderVo.setPostage(new BigDecimal("0"));

        orderVo.setSendTime(DateTimeUtil.dateToStr(order.getSendTime()));
        orderVo.setCreateTime(DateTimeUtil.dateToStr(order.getCreateTime()));
        orderVo.setPaymentTime(DateTimeUtil.dateToStr(order.getPaymentTime()));
        orderVo.setEndTime(DateTimeUtil.dateToStr(order.getSendTime()));
        orderVo.setCloseTime(DateTimeUtil.dateToStr(order.getCloseTime()));


        List<OrderItemVo> orderItemVoList = Lists.newArrayList();

        for (OrderItem orderItem : orderItemList) {
            OrderItemVo orderItemVo = assembleOrderItemVo(orderItem);
            orderItemVoList.add(orderItemVo);
        }

        Shipping shipping = shippingMapper.selectByPrimaryKey(order.getShippingId());
        if (shipping != null) {
            ShippingVo shippingVo = assembleShippingVo(shipping);
            orderVo.setShippingVo(shippingVo);
            orderVo.setReceiverName(shipping.getReceiverName());
        }

        return orderVo;
    }

    private ShippingVo assembleShippingVo(Shipping shipping) {
        ShippingVo shippingVo = new ShippingVo();
        shippingVo.setReceiverAddress(shipping.getReceiverAddress());
        shippingVo.setReceiverCity(shipping.getReceiverCity());
        shippingVo.setReceiverDistrict(shipping.getReceiverDistrict());
        shippingVo.setReceiverMobile(shipping.getReceiverMobile());
        shippingVo.setReceiverName(shipping.getReceiverName());
        shippingVo.setReceiverPhone(shipping.getReceiverPhone());
        shippingVo.setReceiverProvince(shipping.getReceiverProvince());
        shippingVo.setReceiverZip(shipping.getReceiverZip());
        return shippingVo;
    }

    private OrderItemVo assembleOrderItemVo(OrderItem orderItem) {
        OrderItemVo orderItemVo = new OrderItemVo();
        orderItemVo.setOrderNo(orderItem.getOrderNo());
        orderItemVo.setProductId(orderItem.getProductId());
        orderItemVo.setQuantity(orderItem.getQuantity());
        orderItemVo.setProductName(orderItem.getProductName());
        orderItemVo.setCreateTime(DateTimeUtil.dateToStr(orderItem.getCreateTime()));
        orderItemVo.setTotalPrice(orderItem.getTotalPrice());
        orderItemVo.setProductImage(orderItem.getProductImage());

        return orderItemVo;
    }

    private void reduceProductStock(List<OrderItem> orderItemList) {
        for (OrderItem orderItem : orderItemList) {
            Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
            product.setStock(product.getStock() - orderItem.getQuantity());
            productMapper.updateByPrimaryKeySelective(product);
        }

    }

    private void clearCart(List<OrderItem> orderItemList) {
        for (OrderItem orderItem : orderItemList) {
            cartMapper.deleteByPrimaryKey(orderItem.getId());
        }
    }

    private Order assembleOrder(Integer userId, Integer shippingId, BigDecimal payment) {
        Order order = new Order();
        order.setShippingId(shippingId);
        order.setPayment(payment);
        order.setPaymentType(Const.PaymentTypeEnum.ONLINE_PAY.getCode());
        order.setOrderNo(generateOrderNo());
        order.setPostage(0);
        order.setUserId(userId);

        //TODO 发货时间和付款时间
        //PaymentTime,sendTime,closeTime都是需要填写的
        order.setPaymentTime(new Date(System.currentTimeMillis()));
        order.setSendTime(new Date(System.currentTimeMillis()));
        order.setCloseTime(new Date(System.currentTimeMillis()));

        int rowCount = orderMapper.insertSelective(order);
        if (rowCount > 0) {
            return order;
        }
        return null;
    }

    private long generateOrderNo() {
        long currentTime = System.currentTimeMillis();
        return currentTime + new Random().nextInt(100);
    }

    private BigDecimal getOrderTotalPrice(List<OrderItem> data) {
        BigDecimal payment = new BigDecimal("0");
        if (CollectionUtils.isNotEmpty(data)) {
            for (OrderItem orderItem : data) {
                payment = payment.add(orderItem.getTotalPrice());
            }
        }
        return payment;
    }

    private ServerResponse generateOrderItem(Integer userId, List<Cart> cartList) {

        List<OrderItem> orderItemList = Lists.newArrayList();

        if (CollectionUtils.isEmpty(cartList)) {
            return ServerResponse.createByErrorMessage("购物车为空");
        }
        //获取商品id，查询商品库存和状态，是否是售卖状态
        for (Cart cart : cartList) {
            Product product = productMapper.selectByPrimaryKey(cart.getProductId());
            if (Const.ProductStatus.ON_SALE != product.getStatus()) {
                return ServerResponse.createByErrorMessage("产品:" + product.getName() + " 不在售卖状态");
            }
            //产品在售卖状态，检查库存是否充足(购物车对象应该已经检查过了？)
            if (product.getStock() < cart.getQuantity()) {
                return ServerResponse.createByErrorMessage("产品:" + product.getName() + " 超出商品库存");
            }
            //计算商品总价格
            OrderItem orderItem = new OrderItem();
            orderItem.setProductId(product.getId());
            orderItem.setProductName(product.getName());
            orderItem.setProductImage(product.getMainImage());
            orderItem.setCurrentUnitPrice(product.getPrice());
            orderItem.setQuantity(cart.getQuantity());
            orderItem.setTotalPrice(BigDecimalUtil.mul(product.getPrice().doubleValue(), cart.getQuantity().doubleValue()));
            orderItem.setUserId(userId);

            orderItemList.add(orderItem);
        }

        return ServerResponse.createBySuccess(orderItemList);
    }


}
